package com.night.student.controller;

import com.night.common.entity.PageBean;
import com.night.common.entity.ResultVo;
import com.night.common.entity.administration.CourseManager;
import com.night.common.entity.administration.Teacher;
import com.night.common.entity.student.*;
import com.night.student.exception.*;
import com.night.student.feignclient.CourseFeign;
import com.night.student.service.EvaluateService;
import com.night.student.service.LessonService;
import com.night.student.service.ScoreService;
import com.night.student.service.StudentService;
import lombok.Getter;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Mr.Wang
 * @ClassName: StudentController
 * @Description: //TODO
 * @date: 2022/10/19-10:49
 */
@RestController
@RequestMapping("/api/v1/student")
public class StudentController {
    @Autowired
    LessonService lessonService;

    @Autowired
    StudentService studentService;

    @Autowired
    EvaluateService evaluateService;

    @Autowired
    ScoreService scoreService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    CourseFeign courseFeign;

    @Autowired
    RedissonClient redissonClient;

    //查自己课表
    @GetMapping("/mycourse")
    public ResultVo<List<CourseManager>[]> getCourseByStudent(int studentId,int classId){
        return new ResultVo<>(lessonService.getCourseByStudent(studentId,classId));
    }

    //查自己信息
    @GetMapping("/myinfo/{studentId}")
    public ResultVo<Student> getInfoById(@PathVariable int studentId){
        return new ResultVo<>(studentService.getInfo(studentId));
    }

    //根据学号查自己信息
    @GetMapping("/myinfo/num/{studentNumber}")
    public ResultVo<Student> getInfoByNumber(@PathVariable String studentNumber){
        return new ResultVo<>(studentService.getInfoByNumber(studentNumber));
    }

    //修改自己信息
    @PostMapping("/myinfo/update")
    public ResultVo<String> updateInfoById(@RequestBody Student student){
        studentService.update(student);
        return ResultVo.SUCCESS;
    }

    //根据班级id查学生
    @GetMapping("/student/{classId}")
    public ResultVo<List<Student>> getStudentByClassId(@PathVariable int classId){
        return new ResultVo<>(studentService.getByClassId(classId));
    }

    //新增单个学生
    @PostMapping("/student/{classId}")
    public ResultVo<String> addStudent(@RequestBody Student student){
        studentService.add(student);
        return ResultVo.SUCCESS;
    }

    //学生查自己辅导员
    @GetMapping("/mycounselor/{studentId}")
    public ResultVo<Teacher> getCourseByStudent(@PathVariable int studentId){
        return new ResultVo<>(studentService.getByStudent(studentId));
    }

    //进行选课
    @PostMapping("/selectcourse")
    public ResultVo<String> selectCourse(@RequestBody SelectCourseVo selectCourseVo){
        try {
            lessonService.SelectCourse(selectCourseVo);
        }catch(MultiRequestException e){
            return new ResultVo<>(801,"重复请求");
        }catch(RepeatSelectException e){
            return new ResultVo<>(802,"重复选课");
        }catch(TimeConflictException e){
            return new ResultVo<>(803,"时间冲突");
        }catch(FullNumsException e){
            return new ResultVo<>(804,"人数已满");
        }catch(ServiceException e){
            return ResultVo.FAIL;
        }
        return ResultVo.SUCCESS;
    }

    //展示所有选修课
    @PostMapping("/selectcourse/get")
    public ResultVo<PageBean<List<CourseManager>>> getSelectCourse(@RequestBody SelectCourseManagerVo selectCourseManagerVo){
        CourseManager courseManager = selectCourseManagerVo.getCourseManager();
        if("".equals(courseManager.getCourseName()) && "".equals(courseManager.getCourseWeek()) && courseManager.getCourseCredit()==0){
            RLock lock = redissonClient.getLock("lock");
            lock.lock();  //分布式锁防止缓存击穿
            PageBean<List<CourseManager>> result = (PageBean<List<CourseManager>>)redisTemplate.opsForHash().get("selectcourse",String.valueOf(selectCourseManagerVo.getPage()));
            if(result==null){
                result=courseFeign.getCourseByCondition(selectCourseManagerVo).getData();
                redisTemplate.opsForHash().put("selectcourse",String.valueOf(selectCourseManagerVo.getPage()),result);
                redisTemplate.expire("selectcourse",1, TimeUnit.DAYS);
            }
            lock.unlock();
            return new ResultVo<>(result);
        }
        return courseFeign.getCourseByCondition(selectCourseManagerVo);
//        return new ResultVo<>((PageBean<List<CourseManager>>)redisTemplate.opsForHash().get("selectcourse",String.valueOf(selectCourseManagerVo.getPage())));
    }

    //学生评价
    @PostMapping("/evaluate")
    public ResultVo<String> doEvaluate(@RequestBody Evaluate evaluate){
        evaluateService.update(evaluate);
        return ResultVo.SUCCESS;
    }

    //待评价
    @GetMapping("/evaluate/my/{studentId}")
    public ResultVo<List<Evaluate>> getEvaluate(@PathVariable int studentId){
        return new ResultVo<>(evaluateService.getUnevaluate(studentId));
    }

    //根据老师id或课程id查评价,或评分低于给定值或高的评价
    @PostMapping("/evaluate/condition")
    public ResultVo<PageBean<List<Evaluate>>> getEvaluateByCondition(@RequestBody EvaluateVo evaluateVo){
        PageBean<List<Evaluate>> evaluates = evaluateService.getByCondition(evaluateVo);
        return new ResultVo<>(evaluates);
    }

    //根据老师id得到平均评分
    @GetMapping("/evaluate/teacher/{teacherId}")
    public ResultVo getScoreByTeacher(@PathVariable int teacherId){
        return new ResultVo<>(evaluateService.getScoreByTeach(teacherId));
    }

    //根据课程ids得到平均评分
    @GetMapping("/evaluate/course/{courseId}")
    public ResultVo getScoreByCourse(@PathVariable int courseId){
        return new ResultVo<>(evaluateService.getScoreByCourse(new int[]{courseId}));
    }

    //根据条件查成绩(学期、是否通过)
    @PostMapping("/score/condition")
    public ResultVo getScoreByCondition(@RequestBody ScoreVo scoreVo){
        return new ResultVo<>(scoreService.getScoreByCondition(scoreVo));
    }

    //老师录入单个成绩(修改)
    @PostMapping("/score/update")
    public ResultVo addScore(@RequestBody Score score){
        scoreService.addSelectScore(score);
        return ResultVo.SUCCESS;
    }


}
